<template>
  <el-row type="flex" align="middle" class="form-item">
    <!-- label -->
    <el-row class="item-label" justify="end">
      <el-row 
        v-if="schema.option?.required" 
        type="flex" 
        class="required"
      >*</el-row>
      {{ schema.label }}
    </el-row>
    <!-- value -->
    <el-row class="item-value">
      <el-input
        v-model="dtoValue"
        :class="[validTips ? 'component valid-border' : 'component']"
        :placeholder="placeholder"
        v-bind="schema.option"
        @focus="onFocus"
        @blur="onBlur"
      />
    </el-row>
    <!-- tips -->
    <el-row
      v-if="validTips"
      class="valid-tips"
    >{{ validTips }}
    </el-row>
  </el-row>
</template>

<script setup>
import { ref, toRefs, onMounted, watch, inject } from 'vue';
const ajv = inject('ajv');
const props = defineProps({
  schemaKey: String,
  schema: Object,
  model: String,
});
const name = ref('input');
const { schemaKey, schema } = props;
const { model } = toRefs(props);
const validTips = ref(null);
const placeholder = ref('');
const dtoValue = ref();
const initData = () => {
  dtoValue.value = model.value ?? schema.option?.default;
  const { minLength, maxLength, pattern } = schema;
  const ruleList = [];
  if (schema.option?.placeholder) {
    ruleList.push(schema.option.placeholder);
  }
  if (minLength) {
    ruleList.push(`最小长度：${minLength}`);
  }
  if (maxLength) {
    ruleList.push(`最大长度：${maxLength}`);
  }
  if (pattern) {
    ruleList.push(`格式：${pattern}`);
  }
  placeholder.value = ruleList.join(' ');
};
onMounted(() => {
  initData();
});
watch([model, schema],() => {
    initData();
  },{ deep: true },
);
/**
 * 校验
 */
const validate = () => {
  validTips.value = null;
  const { type } = schema;
  // 校验是否必填
  if (schema.option?.required && !dtoValue.value) {
    validTips.value = '不能为空';
    return false;
  }
  // ajv 校验schema
  if (dtoValue.value) {
    const ajvValidate = ajv.compile(schema);
    const valid = ajvValidate(dtoValue.value);
    if (!valid && ajvValidate.errors && ajvValidate.errors[0]) {
      const { keyword, params } = ajvValidate.errors[0];
      if (keyword === 'type') {
        validTips.value = `类型必须为${type}`;
      } else if (keyword === 'minLength') {
        validTips.value = `长度不能小于${params.limit}`;
      } else if (keyword === 'maxLength') {
        validTips.value = `长度不能大于${params.limit}`;
      } else if (keyword === 'pattern') {
        validTips.value = '格式不正确';
      } else {
        console.log(ajvValidate.errors[0]);
        validTips.value = '不符合要求';
      }
      return false;
    }
  }
  return true;
};
/**
 * 获取组件值
 */
const getValue = () => {
  return dtoValue.value != undefined ? { [schemaKey]: dtoValue.value } : {};
};
const reset = () => {
  dtoValue.value = undefined;
  validTips.value = null;
};
const onFocus = () => {
  validTips.value = null;
};
const onBlur = () => {
  validate();
};
defineExpose({
  validate,
  getValue,
  reset,
  name,
});
</script>

<style scoped lang="less"></style>